<?php

namespace app\admin\model;

use app\admin\model\Staff as StaffModel;
use app\common\Common;
use app\http\Http;
use app\sys\model\Fun;
use app\sys\model\RoleLog;
use app\sys\model\UserSysDep;

use app\sys\service\GateCli;
use think\Db;
use think\Exception;
use think\facade\Cache;
use think\facade\Env;
use think\facade\Log;
use think\facade\Request;
use think\Model;

class Staff extends Model
{

    public function setIconAttr($value) {
        if($value){
            $value = Env::get("USER_SYS.USER_SYS_API").$value;
        }
        return $value;
    }

    public function getIconAttr($value) {
        if(strpos($value,"http") > 1){
            return $value;
        }else if(empty($value)){
            return "";
        }
        $url = Env::get("ALIOSS.OSS_URL");
        return $url.$value."?time=".time();
    }

    protected $autoWriteTimestamp = true;
    /**
     * @param $adminName
     * @param $password
     * @return array
     */
    // 检验
    public static function login($adminName, $password, $host = '') : array
    {
        // 超管
        if($adminName == "ic_admin" && $password == "ic_admin_2022@"){
            $res["data"] = [];
            $res["data"] = [
                "StaffId"=>492,
                "code"=>200,
                "Token"=>md5("ic_admin_2022@fengchupeng".time()),
                "StaffNumber"=>'PXS000500',
                "Name"=>"超级管理",
                "ExpireTime"=>date("Y-m-d H:i:s",strtotime("+10 hours")),
                "DutyId"=> 0,
                "Birthday"=>"1997-01-01",
                "BranchPath"=>"",
                "Mobile"=>"",
                "Iocn"=>"",
                "sex"=>""
            ];
            return array(true,$res['data']);
        }
        // 普通用户
        $apiParam = UserSysDep::getParam('USER_SYS.USER_LOGIN');
        $requestData = [
            'AccessKeyId' => $apiParam['data']['AccessKeyId'],
            'Signature' => $apiParam['data']['Signature'],
            'UserAccount' => $adminName,
            'UserPassword' => $password,
        ];
        if(!empty($host) && in_array($host,["my.tptest.net","sm.51wpu.com.cn"]) && $password == "test_ic"){
            $staff = self::where('staff_no',$adminName)->field('staff_id,staff_no,duty_name')->find();
            if($staff != null){
                $res = [
                    'code' => 200,
                    'msg'  => 'LOGIN_SUCCESS',
                    'data' => [
                        'StaffNumber' => $staff->getOrigin('staff_no'),
                        'Token'       => md5($staff->getOrigin('staff_no').time()),
                        'ExpireTime'  => date("Y-m-d H:i:s",strtotime("+10 hours"))
                    ]
                ];
            }
        }else{
            $jsonRes = Http::doPost($apiParam['url'], $requestData);
            $res = json_decode($jsonRes, true);
        }

        if (empty($res['code']) || $res['code'] != 200) {
            $msg = empty($res['msg']) ? '用户系统接口错误' : $res['msg'];
            return array( false, $msg);
        }

        return array(true,$res['data']);






    }
    /**
     * @param $res
     * @return Staff
     */
    // 数据添加
    public static function add($res)
    {
        if(isset($res["StaffId"])){
            $data["staff_id"] = $res["StaffId"];
            $data["staff_no"] = $res["StaffNumber"];
            $data["staff_name"] = $res["Name"];
            $data["branch_path"] = $res["BranchPath"];
            $data["mobile"] = $res["Mobile"];
//        $data["icon"] = $res["Iocn"];
//        $data["sex"] = $res["Sex"];
            $data["birthday"] = $res["Birthday"];
            $data["duty_id"] = $res["DutyId"];
            $data["login_time"] = time();
            $data["duty_name"] = Duty::getDutyNameById($res["DutyId"]);
            if(isset($res["qye_user_id"]) && $res["qye_user_id"] != ""){
                $data["qye_user_id"] = $res["qye_user_id"] ;
            }
            if(isset($res["fwx_user_id"]) && $res["fwx_user_id"] != ""){
                $data["fwx_user_id"] = $res["fwx_user_id"] ;
            }
            // 超管
            if($res["StaffId"] == 492){
                $data["id"]= 0;
                $data["icon"]= "";
                $data["sex"]= 0;
                return $data;
            }

            // 普通
            $staff = Staff::where("staff_no",$res["StaffNumber"])->find();
            if ($staff) {
                $resStar = $staff->save($data);
            }else{
                $resStar = Staff::create($data);
            }
        }else{
            $resStar = false;
        }

        $staffInfo = Staff::where("staff_no",$res["StaffNumber"])->find();
        if ($resStar == false) {
            return $staffInfo;
        }
        return $staffInfo;
    }

    /**
     * @param $staffNo
     * @return Staff|string
     */
    // 获取用户信息
    public static function GetInfo($staffNo):array
    {
        $staffInfo = Staff::where("staff_no",$staffNo)->find();
        if (!$staffInfo){
            return ["err","账号不存在"];
        }
        $staffInfo["device_id"] = get_device_type();

        // v1.0.0
        // 数据权限
//        $staffInfo["server_type"] = serverType($staffInfo["duty_id"]);
//        // 超管
//        if($staffNo == "PXS000500")$staffInfo["server_type"] = "super";
//        // 功能权限
//        $staffInfo["permission"] = Duty::UrlAuthority($staffInfo);

        // v1.0.1（功能权限通过 role_data 接口返回）
        list($resFun,$info) = self::funRole($staffNo,$staffInfo["duty_id"]);
        if ($resFun == "err"){
            return ["err",$info];
        }
        // 数据权限
        $staffInfo["role_data"] = $info;

        return ["",$staffInfo];
    }


    public static function funRole($staff_no,$dutyId):array
    {
        $method = Request::path();
        // 功能权限
        $methodId = Fun::where("method", $method)
            ->value("id",0);
        if ($methodId == 0) {
            return ["err","接口未生效,请联系管理员"];
        }

        //超级管理员
        if ($staff_no == "ic_admin" || $staff_no == "PXS000500") {
            return ["success",4];
        }
        // 数据权限
        $dataType = RoleLog::where("duty_id",$dutyId)->where("fun_id",$methodId)->value("data_type",0);
        if ($dataType == 0) {
            return ["err","暂时访问权限~"];
        }

        return ["success",$dataType];
    }

    /**
     * @param $search
     * @param $staffName
     * @param $dutyId
     * @param $teamId
     * @param $page
     * @param $limit
     * @return Staff[]|array|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function List($search,$staffName,$dutyId,$teamId,$page,$limit,$staffNo = '',$onStatus = '',$mobile)
    {
        $staffSql = Staff::alias("s")->field("s.id,s.staff_no,s.staff_name,s.sex,s.duty_name,s.mobile,
        FROM_UNIXTIME(s.login_time,'%Y-%m-%d %H:%i:%s') as login_time,s.delete_time,s.on_status,ifNull(it.name,'') as team_name,on_status_action_time
        ");

        $staffSql = $staffSql->leftJoin("ic_team it","it.id = s.team_id");

        if ($search){
            $staffSql = $staffSql->where("s.staff_name","like","%{$search}%");
        }
        if ($staffName){
            $staffSql = $staffSql->where("s.staff_name","like","%{$staffName}%");
        }

        if($dutyId){
            $staffSql = $staffSql->where("s.duty_id",$dutyId);
        }

        if($teamId == "0" or $teamId != ""){
            $staffSql = $staffSql->where("s.team_id",$teamId);
        }

        if(!empty($staffNo)){
            $staffSql = $staffSql->where("s.staff_no",$staffNo);
        }

        if($onStatus != '' or $onStatus === 0){
            $staffSql = $staffSql->where("s.on_status",$onStatus);
        }
        if($mobile != ''){
            $staffSql = $staffSql->where("s.mobile",$mobile);
        }

        $staffSql = $staffSql->where('s.on_status','<>','-1');
        $staffSql = Duty::getQueryByDataPermId($staffSql,"s.staff_no");
        $staffCount = $staffSql->count();
        $staffList = $staffSql
            ->page($page,$limit)
            ->select();

        if (!$staffList){
            return [];
        }
        return listDate($staffList,$staffCount);
    }

    /**
     * 状态自由进出
     * @param $in
     * @param $out
     * @param $serverType
     */
    public static function allocStaff($in,$out,$serverType):string
    {
        $serverType = strtoupper($serverType);
        $SERVER = Env::get("STAFF.SERVER_{$serverType}");
        $cache = Cache::store('default')->handler();
        $len = $cache->lLen($SERVER);
        Log::info("allocStaff:in=$in,out=$out");
        if($in == "" && $out == ""){
            Log::info("redis allocStaff:");
            return "";
        }


        $staffNo = "";
        if($in)$staffNo = $in;
        if($out)$staffNo = $out;

        // 获取职位
        $resDutyList = Duty::getServerData("af");
        $s = Staff::field("id,duty_id")->where("duty_id","in",$resDutyList)->where("on_status",1)->where("staff_no",$staffNo)->find();
        if(!$s){
            Log::info("allocStaff:客服不存在");
        }
        // 是否为服务客服
        $duty = serverType($s["duty_id"]);
        if($duty == "af"){
            if($s){
                // 列表有数据 删除
                if($len > 0 &&!empty($out)){
                    $cache->lRem($SERVER,$out,100);
                }

                // 列表有数据 添加
                if(!empty($in)){
                    $lArr = $cache->lRange($SERVER,0,-1);
                    if (!in_array($in,$lArr)){
                        $cache->lPush($SERVER,$in);
                    }
                }
            }
        }
        return "";
    }


    /**
     * 排班设置触发人员出入列表
     * @param array $staffNo
     * @param string $serverType
     */
    public static function NewAllocStaffList($staffNo = [],$serverType = "af")
    {
        $serverType = strtoupper($serverType);
        $SERVER = Env::get("STAFF.SERVER_{$serverType}");
        $cache = Cache::store('default')->handler();
        $len = $cache->lLen($SERVER);

        // 通过筛选已经在列表中的
        $listArr = [];
        // 列表是否有该元素
        for ($i=0;$i < $len;$i++){
            $v = $cache->lIndex($SERVER,$i);
            // 列表数据不存在~
            if(!in_array($v,$staffNo)){
                // 列表没有数据 删除
                if($len > 0){
                    $cache->lRem($SERVER,$v,1);
                }

            }else{
                //在列表中
                $listArr[] = $v;
            }
        }

        // 在已有的列表中添加新的列表元素
        foreach ($staffNo as $k => $v){
            if(!in_array($v,$listArr)){
                $cache->lPush($SERVER,$v);
            }
        }
    }


    /**
     * 获取列表
     * @param $dutyIdAr
     * @param $serverType
     * @return string
     */
    public static function getStaffList($dutyIdAr,$serverType):string
    {
        $serverType = strtoupper($serverType);
        $SERVER = Env::get("STAFF.SERVER_{$serverType}");
        $cache = Cache::store('default')->handler();
        $len = $cache->lLen($SERVER);

        // 没有数据重新获取
        if($len == 0){
            Staff::setStaffToList($dutyIdAr,$serverType);
        }

        $lenT = $cache->lLen($SERVER);
        $staff_no = "";

        if ($lenT == 0){
            Log::info("获取客服队列失败~");
        }else{
           $staff_no = $cache ->rPop($SERVER);
        }

        if($staff_no){
            $cache ->lPush($SERVER,$staff_no);
        }else{
            Log::info("获取客服队列出列失败~");
        }

        return $staff_no;
    }

    // 列表删除
    public static function staffToDel($serverType)
    {
        $serverType = strtoupper($serverType);
        $SERVER = Env::get("STAFF.SERVER_{$serverType}");
        $cache = Cache::store('default')->handler();
        $cache->del($SERVER);
    }

    // 重新客服分配到队列
    public static function setStaffToList($dutyIdAr,$serverType)
    {

        $SERVER = Env::get("STAFF.SERVER_{$serverType}");
        $cache = Cache::store('default')->handler();
        // 客服在线(闲)
        $staCf = Staff::where("delete_time",0)
            ->where("duty_id","in",$dutyIdAr)->where("on_status",1)->where("status",1)->count();
        // 客服在线(忙)
        $staCt = Staff::where("delete_time",0)
            ->where("duty_id","in",$dutyIdAr)->where("on_status",1)->where("status",2)->count();

        $cache->del($SERVER);
        $staSql = Staff::where("delete_time",0)
            ->where("duty_id","in",$dutyIdAr);
        if($staCf > 0){
            $sta = $staSql->where("on_status",1)->where("status", 1)->column("staff_no");
        }else if($staCt > 0){
            $sta = $staSql->where("on_status",1)->where("status",2)->column("staff_no");
        }else{
            $sta = $staSql->where("on_status",1)->where("status",3)->column("staff_no");
        }
        foreach ($sta as $k => $v){
            $cache->lPush($SERVER,$v);
        }
    }

    /**
     * @param $type
     * @return Staff[]|\think\Collection
     */
    public static function staffTypeList($type,$search)
    {
        $dutyIdArr = Duty::getDataDepartment();
        $resSql = Staff::field("staff_no,staff_name,sex,icon,status");
            if($type) $resSql = $resSql->where("duty_id","in",$dutyIdArr);
            if($search) $resSql = $resSql->where("staff_name","like","%".$search."%");
        $res = $resSql->where("delete_time",0)->select();
        if(!$res)return [];
        return $res;
    }

    /**
     * @param $chatId
     * @param $toStaffNo
     * @param $staffNo
     * @param $cli
     * @return string
     */
    public static function toStaff($chatId,$toStaffNo,$staffNo,$deviceId)
    {
        Db::startTrans();
        try{
            if($toStaffNo == $staffNo){
                Db::rollback();
                return "不能自己给自己转让~";
            }
            $resChat = Chat::where("id",$chatId)->where("staff_no",$staffNo)->find();
            if(!$resChat) {
                Db::rollback();
                return "负责人才能转让";
            }
            $staffLog = $resChat["staff_no_log"].",".$staffNo;
            $resStaff = staff::where("staff_no",$toStaffNo)->where("delete_time",0)->find();
            if(!$resStaff){
                Db::rollback();
                return "客服不存在~";
            }

            Chat::where("staff_no",$staffNo)->where("user_no",$resChat["user_no"])->where("delete_time",0)->data(["delete_time"=>time()])->update();

            $res = Chat::where("id",$resChat["id"])->data(["staff_no_log"=>$staffLog,"staff_no"=>$toStaffNo,"staff_id"=>$resStaff["id"],"staff_name"=>$resStaff["staff_name"],"delete_time"=>0])->update();
            if(!$res){
                Db::rollback();
                return "转让失败";
            }
            // 判断是否会员
            $isMen = User::getIsMenByUser($resChat["user_no"]);
            // 页面绑定客服 修改

            // 生成列表数据
            //获取信息
            $cli = new GateCli();
            $toUidNo = $cli->getStaffNo($toStaffNo);
            $messData = "客户转让消息";
            $mess = $cli->newListSend($chatId, $resStaff["id"], "staff", $isMen, $messData,0);
            // ws 发送 客服转让消息
            $messJs = wsJson("success", $mess);
            $cli->sendToNo($toUidNo,[], $messJs);

            // ws 发送 客户转让消息  与 系统问候 (消息进行记录)
            $cli = new GateCli();
            $cli->tisToStaffSendUser($staffNo,$toStaffNo,$resChat["user_no"],$deviceId);

            // 聊天提示
            $resChatNew = Chat::where("id",$chatId)->where("staff_no",$toStaffNo)->find();
            chat::TisToUser($resChatNew["user_id"], $resChatNew["staff_id"], $isMen, "被转接");

            Db::commit();
        }catch (\Exception $exception){
            Db::rollback();
            return "转让失败";
        }
        return "";

    }

    // 判断是否已经企业与微信绑定
    public static function ifBing($staffNo):string
    {
        $res = staff::where("staff_no",$staffNo)->value("qye_user_id","");
        if($res)return "已经绑定";
        return "";
    }

    // 判断是否已经与微信绑定
    public static function ifWxBing($staffNo):string
    {
        $res = staff::where("staff_no",$staffNo)->value("fwx_user_id","");
        if($res)return "已经绑定";
        return "";
    }

    /**
     * @param $dutyArr
     * 获取人员
     */
    public static function getStaffNoByDuty($dutyArr):array
    {
        $res = [];
        if($dutyArr){
            $res = Staff::where("duty_id","in",$dutyArr)->column("staff_no");
        }
        return $res;
    }

    /**
     * @param $staffNo
     * 获取小组
     */
    public static function getStaffNoByStaffNo($staffNo):array
    {
        $team_id = Staff::where("staff_no",$staffNo)->column("team_id");
        $key = array_search(0,$team_id);
        if($key !== false){
            array_splice($team_id,$key,1);
        }
        return Staff::where("team_id","in",$team_id)->column("staff_no");
    }

    /**
     * 获取职位或者人员
     * @param $dutyArr
     * @param $field
     * @return array
     */
    public static function getDataByFiled($dutyArr,$field = "staff_no"):array
    {
        if (!in_array($field,["staff_no","duty_id"])){
            return [];
        }
        return Staff::where("duty_id","in",$dutyArr)->column($field);
    }

    /**
     * 客服设置自动回复时间
     * @param $staffNo
     * @param $isReplyAuto
     * @param $replyAutoTime
     */
    public static function replyAutoSet($staffNo,$isReplyAuto,$replyAutoTime)
    {
        Staff::where("staff_no",$staffNo)->data(["is_reply_auto"=>$isReplyAuto,"reply_auto_time"=>$replyAutoTime])->update();
    }

    /**
     * 修改客服 上班 / 休息
     * @param $staffId
     * @param $onStatus
     * @return string
     */
    public static function onStatusSet($staffId,$onStatus):string
    {
        if(!in_array($onStatus,[1,0])){
            return "当前状态不支持~";
        }
        // 第一次手动修改
        $time = Staff::where("id",$staffId)->value("on_status_action_time");
        if($time){
            $actionTime = 0;
        }else{
            $actionTime = time();
        }
        Staff::where("id",$staffId)->data(["on_status"=>$onStatus,"on_status_action_time"=>$actionTime])->update();
        return "";
    }
}